home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / share / hplip / base / mdns.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2009-10-28  |  8KB  |  293 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import sys
  5. import time
  6. import socket
  7. import select
  8. import struct
  9. import random
  10. import re
  11. import cStringIO
  12. from g import *
  13. import utils
  14. MAX_ANSWERS_PER_PACKET = 24
  15. QTYPE_A = 1
  16. QTYPE_TXT = 16
  17. QTYPE_SRV = 33
  18. QTYPE_AAAA = 28
  19. QTYPE_PTR = 12
  20. QCLASS_IN = 1
  21.  
  22. def read_utf8(offset, data, l):
  23.     return (offset + l, data[offset:offset + l].decode('utf-8'))
  24.  
  25.  
  26. def read_data(offset, data, l):
  27.     return (offset + l, data[offset:offset + l])
  28.  
  29.  
  30. def read_data_unpack(offset, data, fmt):
  31.     l = struct.calcsize(fmt)
  32.     return (offset + l, struct.unpack(fmt, data[offset:offset + l]))
  33.  
  34.  
  35. def read_name(offset, data):
  36.     result = ''
  37.     off = offset
  38.     next = -1
  39.     first = off
  40.     while True:
  41.         l = ord(data[off])
  42.         off += 1
  43.         if l == 0:
  44.             break
  45.         
  46.         t = l & 192
  47.         if t == 0:
  48.             (off, utf8) = read_utf8(off, data, l)
  49.             result = ''.join([
  50.                 result,
  51.                 utf8,
  52.                 '.'])
  53.             continue
  54.         if t == 192:
  55.             if next < 0:
  56.                 next = off + 1
  57.             
  58.             off = (l & 63) << 8 | ord(data[off])
  59.             if off >= first:
  60.                 log.error('Bad domain name (circular) at 0x%04x' % off)
  61.                 break
  62.             
  63.             first = off
  64.             continue
  65.         log.error('Bad domain name at 0x%04x' % off)
  66.         break
  67.     if next >= 0:
  68.         offset = next
  69.     else:
  70.         offset = off
  71.     return (offset, result)
  72.  
  73.  
  74. def write_name(packet, name):
  75.     for p in name.split('.'):
  76.         utf8_string = p.encode('utf-8')
  77.         packet.write(struct.pack('!B', len(utf8_string)))
  78.         packet.write(utf8_string)
  79.     
  80.  
  81.  
  82. def create_outgoing_packets(answers):
  83.     index = 0
  84.     num_questions = 1
  85.     first_packet = True
  86.     packets = []
  87.     packet = cStringIO.StringIO()
  88.     answer_record = cStringIO.StringIO()
  89.     while True:
  90.         packet.seek(0)
  91.         packet.truncate()
  92.         num_answers = len(answers[index:index + MAX_ANSWERS_PER_PACKET])
  93.         if num_answers == 0 and num_questions == 0:
  94.             break
  95.         
  96.         flags = 512
  97.         if len(answers) - index <= MAX_ANSWERS_PER_PACKET:
  98.             flags = 0
  99.         
  100.         packet.write(struct.pack('!HHHHHH', 0, flags, num_questions, num_answers, 0, 0))
  101.         if num_questions:
  102.             write_name(packet, '_pdl-datastream._tcp.local')
  103.             packet.write(struct.pack('!B', 0))
  104.             packet.write(struct.pack('!HH', QTYPE_PTR, QCLASS_IN))
  105.         
  106.         first_record = True
  107.         for d in answers[index:index + MAX_ANSWERS_PER_PACKET]:
  108.             answer_record.seek(0)
  109.             answer_record.truncate()
  110.             if not first_packet and first_record:
  111.                 first_record = False
  112.                 write_name(answer_record, '_pdl-datastream._tcp.local')
  113.                 answer_record.write(struct.pack('!B', 0))
  114.             else:
  115.                 answer_record.write(struct.pack('!H', 49164))
  116.             answer_record.write(struct.pack('!HH', QTYPE_PTR, QCLASS_IN))
  117.             answer_record.write(struct.pack('!I', 65535))
  118.             rdlength_pos = answer_record.tell()
  119.             answer_record.write(struct.pack('!H', 0))
  120.             write_name(answer_record, d)
  121.             answer_record.write(struct.pack('!H', 49164))
  122.             rdlength = answer_record.tell() - rdlength_pos - 2
  123.             answer_record.seek(rdlength_pos)
  124.             answer_record.write(struct.pack('!H', rdlength))
  125.             answer_record.seek(0)
  126.             packet.write(answer_record.read())
  127.         
  128.         packets.append(packet.getvalue())
  129.         index += 20
  130.         if first_packet:
  131.             num_questions = 0
  132.             first_packet = False
  133.             continue
  134.     return packets
  135.  
  136.  
  137. def detectNetworkDevices(ttl = 4, timeout = 10):
  138.     (mcast_addr, mcast_port) = ('224.0.0.251', 5353)
  139.     found_devices = { }
  140.     answers = []
  141.     
  142.     try:
  143.         s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
  144.         x = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  145.         x.connect(('1.2.3.4', 56))
  146.         intf = x.getsockname()[0]
  147.         x.close()
  148.         s.setblocking(0)
  149.         ttl = struct.pack('B', ttl)
  150.     except socket.error:
  151.         log.error('Network error')
  152.         return { }
  153.  
  154.     
  155.     try:
  156.         s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  157.         s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
  158.     except (AttributeError, socket.error):
  159.         pass
  160.  
  161.     
  162.     try:
  163.         s.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_TTL, ttl)
  164.         s.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(intf) + socket.inet_aton('0.0.0.0'))
  165.         s.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1)
  166.     except Exception:
  167.         e = None
  168.         log.error('Unable to setup multicast socket for mDNS: %s' % e)
  169.         return { }
  170.  
  171.     now = time.time()
  172.     next = now
  173.     last = now + timeout
  174.     delay = 1
  175.     while True:
  176.         now = time.time()
  177.         if now > last:
  178.             break
  179.         
  180.         if now >= next:
  181.             
  182.             try:
  183.                 for p in create_outgoing_packets(answers):
  184.                     log.debug('Outgoing: (%d)' % len(p))
  185.                     log.log_data(p, width = 16)
  186.                     s.sendto(p, 0, (mcast_addr, mcast_port))
  187.             except socket.error:
  188.                 e = None
  189.                 log.error('Unable to send broadcast DNS packet: %s' % e)
  190.  
  191.             next += delay
  192.             delay *= 2
  193.         
  194.         update_spinner()
  195.         (r, w, e) = select.select([
  196.             s], [], [
  197.             s], 0.5)
  198.         if not r:
  199.             continue
  200.         
  201.         (data, addr) = s.recvfrom(16384)
  202.         if data:
  203.             update_spinner()
  204.             y = {
  205.                 'num_devices': 1,
  206.                 'num_ports': 1,
  207.                 'product_id': '',
  208.                 'mac': '',
  209.                 'status_code': 0,
  210.                 'device2': '0',
  211.                 'device3': '0',
  212.                 'note': '' }
  213.             log.debug('Incoming: (%d)' % len(data))
  214.             log.log_data(data, width = 16)
  215.             offset = 0
  216.             (id, flags, num_questions, num_answers, num_authorities, num_additionals) = (offset,)
  217.             log.debug('Response: ID=%d FLAGS=0x%x Q=%d A=%d AUTH=%d ADD=%d' % (id, flags, num_questions, num_answers, num_authorities, num_additionals))
  218.             for question in range(num_questions):
  219.                 update_spinner()
  220.                 (offset, name) = read_name(offset, data)
  221.                 (typ, cls) = (offset,)
  222.                 log.debug('Q: %s TYPE=%d CLASS=%d' % (name, typ, cls))
  223.             
  224.             fmt = '!HHiH'
  225.             for record in range(num_answers + num_authorities + num_additionals):
  226.                 update_spinner()
  227.                 (offset, name) = read_name(offset, data)
  228.                 (offset, info) = read_data_unpack(offset, data, '!HHiH')
  229.                 if info[0] == QTYPE_A:
  230.                     (offset, result) = read_data(offset, data, 4)
  231.                     ip = []([ str(ord(x)) for x in result ])
  232.                     log.debug('A: %s' % ip)
  233.                     y['ip'] = ip
  234.                     continue
  235.                 []
  236.                 if info[0] == QTYPE_PTR:
  237.                     (offset, name) = read_name(offset, data)
  238.                     log.debug('PTR: %s' % name)
  239.                     y['mdns'] = name
  240.                     answers.append(name.replace('._pdl-datastream._tcp.local.', ''))
  241.                     continue
  242.                 '.'.join
  243.                 if info[0] == QTYPE_TXT:
  244.                     (offset, name) = read_data(offset, data, info[3])
  245.                     txt = { }
  246.                     off = 0
  247.                     while off < len(name):
  248.                         l = ord(name[off])
  249.                         off += 1
  250.                         result = name[off:off + l]
  251.                         
  252.                         try:
  253.                             (key, value) = result.split('=')
  254.                             txt[key] = value
  255.                         except ValueError:
  256.                             read_data_unpack(offset, data, '!HH')
  257.                             read_data_unpack(offset, data, '!HH')
  258.                             read_data_unpack(offset, data, '!HHHHHH')
  259.                             pas
  260.                         except:
  261.                             read_data_unpack(offset, data, '!HH')
  262.  
  263.                         off += l
  264.                         continue
  265.                         read_data_unpack(offset, data, '!HH')
  266.                     log.debug('TXT: %s' % repr(txt))
  267.                     y['device1'] = 'MFG:Hewlett-Packard;MDL:%s;CLS:PRINTER;' % txt['ty']
  268.                     if 'note' in txt:
  269.                         y['note'] = txt['note']
  270.                     
  271.                 'note' in txt
  272.                 if info[0] == QTYPE_SRV:
  273.                     (priority, weight, port) = (offset,)
  274.                     ttl = info[3]
  275.                     (offset, server) = read_name(offset, data)
  276.                     log.debug('SRV: %s TTL=%d PRI=%d WT=%d PORT=%d' % (server, ttl, priority, weight, port))
  277.                     y['hn'] = server.replace('.local.', '')
  278.                     continue
  279.                 read_data_unpack(offset, data, '!HHH')
  280.                 if info[0] == QTYPE_AAAA:
  281.                     (offset, result) = read_data(offset, data, 16)
  282.                     log.debug('AAAA: %s' % repr(result))
  283.                     continue
  284.                 read_data_unpack(offset, data, '!HHHHHH')
  285.                 log.error('Unknown DNS record type (%d).' % info[0])
  286.                 break
  287.             
  288.         
  289.         found_devices[y['ip']] = y
  290.     log.debug('Found %d devices' % len(found_devices))
  291.     return found_devices
  292.  
  293.